package com.sec.android.app.myfiles.navigation;

import android.os.Handler;
import android.os.Message;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;

/**
 * <p>
 * NavigationChangedObserver class
 * </p>
 * <p>
 * notify NavigationChanged event to listener
 * </p>
 * 
 * @author jae.bae
 */
public class NavigationChangedObserver {
    private Handler mNotifyPathChangedHandler = new WeakRefHandler(this);

    public interface NavigationChangedListener {
        void onNavigationChanged(NavigationInfo preInfo, NavigationInfo curInfo);
    }

    private final ArrayList<NavigationChangedListener> mObserver = new ArrayList<>();

    /**
     * Add listener
     * 
     * @param listener
     */
    public void add(NavigationChangedListener listener) {
        if (!mObserver.contains(listener)) {
            mObserver.add(listener);
        }
    }

    /**
     * remove listener
     * 
     * @param listener
     */

    public void remove(NavigationChangedListener listener) {
        mObserver.remove(listener);
    }

    /**
     * Notify change event to listeners
     * 
     * @param preInfo previous Info
     * @param curInfo cur Info
     */
    public void notifyPathChanged(NavigationInfo preInfo, NavigationInfo curInfo) {
        NavigationInfo[] naviInfo = new NavigationInfo[] {
                preInfo, curInfo };

        mNotifyPathChangedHandler.sendMessage(mNotifyPathChangedHandler.obtainMessage(0, naviInfo));
    }

    private static class WeakRefHandler extends Handler {
        WeakReference<NavigationChangedObserver> mChangedObserver = null;

        WeakRefHandler(NavigationChangedObserver changedObserver) {
            mChangedObserver = new WeakReference<>(changedObserver);
        }

        public void handleMessage(Message msg) {
            NavigationChangedObserver changedObserver = mChangedObserver.get();
            if (changedObserver == null) {
                return;
            }
            NavigationInfo[] info = (NavigationInfo[])msg.obj;

            if (info != null) {
                try {
                    for (NavigationChangedListener listener : changedObserver.mObserver) {
                        listener.onNavigationChanged(info[0], info[1]);
                    }
                } catch (ConcurrentModificationException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
